
// $mm_boxesEnabled
$mm_brickSizeTU = "0.5 0.5 0.2";
$mm_cellSizeTU = "8 8 8";

datablock StaticShapeData(mm_DrawLine_LineShape) {
	shapeFile = "./selectionbox_border.dts";
};

function mm_rotateVector(%vector, %angle) {
	switch(%angle % 4) {
		case 0: return %vector;
		case 1: return  getWord(%vector, 1) SPC -getWord(%vector, 0) SPC getWord(%vector, 2);
		case 2: return -getWord(%vector, 0) SPC -getWord(%vector, 1) SPC getWord(%vector, 2);
		case 3: return -getWord(%vector, 1) SPC  getWord(%vector, 0) SPC getWord(%vector, 2);
	}
}

function mm_eulerToAxis(%euler) {
	%euler = VectorScale(%euler,$pi / 180);
	%matrix = MatrixCreateFromEuler(%euler);
	return getWords(%matrix,3,6);
}

function mm_drawLine(%pos1, %pos2) {
	%center = vectorAdd(vectorScale(vectorSub(%pos2, %pos1), 0.5), %pos1);
	%length = vectorLen(vectorSub(%pos1, %pos2));
	
	%xRot = 0;
	%yRot = 90 - mRadToDeg(mAtan(getWord(%pos2, 2) - getWord(%pos1, 2), vectorLen(vectorSub(getWords(%pos2, 0, 1), getWords(%pos1, 0, 1)))));
	%zRot = mRadToDeg(mAtan(getWord(%pos2, 1) - getWord(%pos1, 1), getWord(%pos2, 0) - getWord(%pos1, 0)));
	%rot = mm_eulerToAxis(%xRot SPC %yRot SPC %zRot);
	
	%shape = new StaticShape() { datablock = mm_DrawLine_LineShape; };
	//%shape.setNodeColor("ALL", %color);
	%shape.setTransform(%center SPC %rot);
	%shape.setScale(1 SPC 1 SPC %length);
	
	return %shape;
}

function mm_drawBox(%box) {
	%x1 = getWord(%box, 0);
	%y1 = getWord(%box, 1);
	%z1 = getWord(%box, 2);
	%x2 = getWord(%box, 3);
	%y2 = getWord(%box, 4);
	%z2 = getWord(%box, 5);
	return
		mm_drawLine(%x1 SPC %y1 SPC %z1, %x2 SPC %y1 SPC %z1) SPC
		mm_drawLine(%x2 SPC %y1 SPC %z1, %x2 SPC %y2 SPC %z1) SPC
		mm_drawLine(%x2 SPC %y2 SPC %z1, %x1 SPC %y2 SPC %z1) SPC
		mm_drawLine(%x1 SPC %y2 SPC %z1, %x1 SPC %y1 SPC %z1) SPC
		mm_drawLine(%x1 SPC %y1 SPC %z2, %x2 SPC %y1 SPC %z2) SPC
		mm_drawLine(%x2 SPC %y1 SPC %z2, %x2 SPC %y2 SPC %z2) SPC
		mm_drawLine(%x2 SPC %y2 SPC %z2, %x1 SPC %y2 SPC %z2) SPC
		mm_drawLine(%x1 SPC %y2 SPC %z2, %x1 SPC %y1 SPC %z2) SPC
		mm_drawLine(%x1 SPC %y1 SPC %z1, %x1 SPC %y1 SPC %z2) SPC
		mm_drawLine(%x1 SPC %y2 SPC %z1, %x1 SPC %y2 SPC %z2) SPC
		mm_drawLine(%x2 SPC %y1 SPC %z1, %x2 SPC %y1 SPC %z2) SPC
		mm_drawLine(%x2 SPC %y2 SPC %z1, %x2 SPC %y2 SPC %z2);
}

function mm_updateBoxColor(%brick) {
	if($mm_boxesEnabled && %brick.mm_box !$= "") {
		%colorId = %brick.getColorId();
		%colorImg = "Color" @ %colorId @ "SprayCanImage";
		%color = %colorImg.colorShiftColor;
		
		for(%i=0; %i<getWordCount(%brick.mm_box); %i++) {
			%shape = getWord(%brick.mm_box, %i);
			if(isObject(%shape)) %shape.setNodeColor("ALL", %color);
		}
	}
}

function mm_vectorMul(%a, %b) {
	return
		getWord(%a, 0)*getWord(%b, 0) SPC 
		getWord(%a, 1)*getWord(%b, 1) SPC 
		getWord(%a, 2)*getWord(%b, 2);
}

function mm_min(%a, %b) { return %a<%b ? %a : %b; }
function mm_max(%a, %b) { return %a>%b ? %a : %b; }

function mm_normalizeBox(%box) {
	%x1 = getWord(%box, 0);
	%y1 = getWord(%box, 1);
	%z1 = getWord(%box, 2);
	%x2 = getWord(%box, 3);
	%y2 = getWord(%box, 4);
	%z2 = getWord(%box, 5);
	return
		mm_min(%x1, %x2) SPC mm_min(%y1, %y2) SPC mm_min(%z1, %z2) SPC
		mm_max(%x1, %x2) SPC mm_max(%y1, %y2) SPC mm_max(%z1, %z2);
}

function mm_deleteBox(%brick) {
	if(isObject(%brick) && %brick.mm_box !$= "") {
		for(%i=0; %i<getWordCount(%brick.mm_box); %i++) {
			%shape = getWord(%brick.mm_box, %i);
			if(isObject(%shape)) %shape.delete();
		}
		%brick.mm_box = "";
	}
}

function mm_updateBox(%brick) {
	mm_deleteBox(%brick);
	
	%name = %brick.getName();
	%pos = strPos(%name, "_template_");
	if(%pos == -1) { %pos = strPos(%name, "_prop_"); %isProp = 1; }
	if(%pos == 0) {
		%size = strReplace(%name, "_template_", "");
		%size = strReplace(%size, "_prop_", "");
		%pos = strPos(%size, "_");
		if(%pos != -1) %size = getSubStr(%size, 0, %pos);
		%size = strReplace(%size, "x", " ");
		
		if(%isProp) %boxSizeTU = mm_vectorMul(%size, $mm_brickSizeTU);
		else        %boxSizeTU = mm_vectorMul(%size, $mm_cellSizeTU );
		
		%boxSizeTU = mm_rotateVector(%boxSizeTU, %brick.getAngleId());
		
		%data = %brick.getDatablock();
		%brickSizeBG = %data.brickSizeX SPC %data.brickSizeY SPC %data.brickSizeZ;
		%brickSizeTU = mm_vectorMul(%brickSizeBG, $mm_brickSizeTU);
		%startAbsTU = %brick.getPosition();
		%startAbsTU = vectorAdd(%startAbsTU, mm_rotateVector(mm_vectorMul(%brickSizeTU, "-0.5 0.5 -0.5"), %brick.getAngleId()));
		%endAbsTU = vectorAdd(%startAbsTU, %boxSizeTU);
		
		%box = mm_normalizeBox(%startAbsTU SPC %endAbsTU);
		
		if(getWord(%size, 0)!=0 && getWord(%size, 1)!=0 && getWord(%size, 2)!=0) {
			if($mm_boxesEnabled) {
				%brick.mm_box = mm_drawBox(%box);
				mm_updateBoxColor(%brick);
			}
		}
	}
}

package mm_drawBoxes {
	function fxDtsBrick::setName(%brick, %name) {
		parent::setName(%brick, %name);
		mm_updateBox(%brick);
	}
	function fxDtsBrick::setColor(%brick, %color) {
		parent::setColor(%brick, %color);
		mm_updateBoxColor(%brick);
	}
	function fxDtsBrick::onDeath(%brick) {
		mm_deleteBox(%brick);
		parent::onDeath(%brick);
	}
	function fxDtsBrick::onRemove(%brick) {
		mm_deleteBox(%brick);
		parent::onRemove(%brick);
	}
};
activatePackage(mm_drawBoxes);

function mm_callOnAllBricks(%func) {
	%mbg = MainBrickGroup;
	%mbgc = %mbg.getCount();
	for(%bgi=0; %bgi<%mbgc; %bgi++) {
		%bg = %mbg.getObject(%bgi);
		%bgc = %bg.getCount();
		for(%bi=0; %bi<%bgc; %bi++) {
			%brick = %bg.getObject(%bi);
			call(%func, %brick);
		}
	}
}

function mm_drawAllBoxes() {
	mm_callOnAllBricks(mm_updateBox);
}

function mm_deleteAllBoxes() {
	mm_callOnAllBricks(mm_deleteBox);
}

function mm_enableBoxes() {
	if(!$mm_boxesEnabled) {
		$mm_boxesEnabled = 1;
		mm_drawAllBoxes();
	}
}

function mm_disableBoxes() {
	if($mm_boxesEnabled) {
		$mm_boxesEnabled = 0;
		mm_deleteAllBoxes();
	}
}

function mm_toggleBoxes() {
	if($mm_boxesEnabled) mm_disableBoxes();
	else mm_enableBoxes();
}

function serverCmdMazeBox(%c) {
	if(%c.isAdmin) {
		mm_toggleBoxes();
		messageClient(%c, 0, "\c6Boxes " @ ($mm_boxesEnabled ? "Enabled" : "Disabled"));
	}
}
